package com.huw.cameramanagers;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.ScrollDetector;

import com.badlogic.gdx.math.Vector2;
import com.light.gamecomponents.IGameComponents;
import com.light.gamecomponents.physics.RollerPhysicsWorld;
import com.light.roller.Player;
import com.light.roller.Roller;


public class CameraManager implements IUpdateHandler, IGameComponents{
	
	public static final float MainCharacterShowingTime = 1;
	public static final float DoorShowingTime = 4;
	public static final float TouchPointCancelDuration = 2;
	public static final float ShowingSpeed = 300;
	
	private Player m_playerFollowed;
	private Roller m_roller;
	private Camera m_camera;
	private PhysicsWorld m_phyicsWorld;
	private Scene m_scene;
	private CameraGhost m_ghost;
	private boolean touched = false;
	private Vector2 touchedPoint = new Vector2(0,0);
	private Vector2 doorPosition;
	public static enum FollowStatus { ShowingDoor, Back, Gaming, Blacking ,Start};
	public FollowStatus followStatus;

	float counter = MainCharacterShowingTime + DoorShowingTime;
	int backTemp = 1;
	
	public void skipShowingDoor()
	{
		followStatus = FollowStatus.Back;
	}	

	public CameraManager(Roller roller, Player playerFollowed, Camera camera)
	{
		m_playerFollowed = playerFollowed;
		m_roller =  roller;	
		m_camera = camera;
		m_ghost = new CameraGhost(roller, playerFollowed,CameraGhost.FollowStyle.ANDROID);
		doorPosition = new Vector2(0,0);
		followStatus = FollowStatus.Start;	
		counter=MainCharacterShowingTime+DoorShowingTime;

	}
	
	public CameraManager(Roller roller, Player playerFollowed, Camera camera, Vector2 InitialPosition,Vector2 DoorPosition)
	{
		m_playerFollowed = playerFollowed;
		m_roller =  roller;	
		m_camera = camera;
		m_ghost = new CameraGhost(roller, playerFollowed,CameraGhost.FollowStyle.ANDROID,InitialPosition);
		doorPosition = DoorPosition;
		followStatus = FollowStatus.Start;
		counter=MainCharacterShowingTime+DoorShowingTime;
	}
	
	public void onScroll(final ScrollDetector pScollDetector, final TouchEvent pTouchEvent, float pDistanceX, final float pDistanceY) 
	{
		if(followStatus==FollowStatus.Gaming)
		{
			if(touched)
			{
			Vector2 tempV = new Vector2();
			tempV.x = -pDistanceX;
			tempV.y = -pDistanceY;	
			//tempV.x /= 2;
			//tempV.y /= 2;		
			touchedPoint.x+=tempV.x;
			touchedPoint.y+=tempV.y;		
			}
			counter=TouchPointCancelDuration;
		}
	}

	@Override
	public void onLoadEngine() {
		// TODO Auto-generated method stub
		
	}
	

	
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent)
	{
		 if(followStatus==FollowStatus.Gaming)if(pSceneTouchEvent.isActionDown()){touched = true;counter=TouchPointCancelDuration;}
		
		//if(pSceneTouchEvent.isActionUp())dicount = true;
		//if(pSceneTouchEvent.isActionCancel())dicount = true;
		//if(pSceneTouchEvent.isActionOutside())dicount = true;
		
		return true;
	}
	
	
	
	
	public void isActionUp(){touched=false;}
	
	@Override
	public void onLoadResources() { m_ghost.onLoadResources(); }
	@Override
	public void unLoadResources() { m_ghost.unLoadResources(); }
	public Camera getCamera() { return m_camera; }
	public void setCamera(Camera camera) { m_camera = camera; }	
	
	public void onLoadScene(Scene scene,PhysicsWorld physicsWorld)
	{
		m_phyicsWorld = physicsWorld;
		m_scene = scene;
		m_ghost.onLoadScene(scene, physicsWorld);
		((RollerPhysicsWorld)m_phyicsWorld).registerUpdateHandler(this);
				
	}
	
	@Override
	public void removeFromScene(Scene scene, PhysicsWorld physicsWorld) {
		((RollerPhysicsWorld)m_phyicsWorld).unregisterUpdateHandler(this);
		m_ghost.removeFromScene(scene, physicsWorld);
	}

	@Override
	public void onUpdate(float pSecondsElapsed) {
		
		Vector2  tempSprite;
		tempSprite = m_ghost.getCenter();
		if (m_playerFollowed != null)m_camera.setCenter(tempSprite.x, tempSprite.y);
		
        CalculateFollow(pSecondsElapsed);	
        
	}
	
	private int delayLightOn = 1;
	private int VertexCount = 0;
	
	private void VertexShowing(Vector2 tempV)
	{
		tempV.x = (m_roller.CameraVertexList.get(VertexCount).x-m_ghost.getCenter().x);
		tempV.y = (m_roller.CameraVertexList.get(VertexCount).y-m_ghost.getCenter().y);
		
		if(Math.abs(tempV.x)<30)if(Math.abs(tempV.y)<30)VertexCount++;
		
		if(tempV.x-ShowingSpeed>0)tempV.x=ShowingSpeed;
		else if (tempV.x+ShowingSpeed<0)tempV.x=-ShowingSpeed;
		
		if(tempV.y-ShowingSpeed>0)tempV.y=ShowingSpeed;
		else if (tempV.y+ShowingSpeed<0)tempV.y=-ShowingSpeed;
	}
	
	private void CalculateFollow(float pSecondsElapsed)
	{
		Vector2 tempV = new Vector2(0,0);
		
		
		if(followStatus==FollowStatus.Gaming)
		{
			if(!touched)
			{
				touchedPoint.x=m_playerFollowed.getX()+m_playerFollowed.getSizeX()/2;
				touchedPoint.y=m_playerFollowed.getY()+m_playerFollowed.getSizeY()/2;
			}			
			tempV.x = (touchedPoint.x-m_ghost.getCenter().x);
			tempV.y = (touchedPoint.y-m_ghost.getCenter().y);
			
	        if(counter>0)counter-=pSecondsElapsed;
	        else touched = false;
			
		}
		else if(followStatus==FollowStatus.ShowingDoor)
		{
			
			if(counter>DoorShowingTime)
			{
				counter-=pSecondsElapsed;
			}
			else if(m_roller.CameraVertexList!=null&&m_roller.CameraVertexList.size()>VertexCount)
			{
				VertexShowing(tempV);
			}
			else
			{
			tempV.x = (doorPosition.x-m_ghost.getCenter().x);
			tempV.y = (doorPosition.y-m_ghost.getCenter().y);
			
			if(Math.abs(tempV.x)<200)if(Math.abs(tempV.y)<100)counter-=pSecondsElapsed;
			
			if(tempV.x-ShowingSpeed>0)tempV.x=ShowingSpeed;
			else if (tempV.x+ShowingSpeed<0)tempV.x=-ShowingSpeed;
			
			if(tempV.y-ShowingSpeed>0)tempV.y=ShowingSpeed;
			else if (tempV.y+ShowingSpeed<0)tempV.y=-ShowingSpeed;
			
			if(counter<0)followStatus=FollowStatus.Back;
			}
		}
		else if(followStatus==FollowStatus.Back)
		{
			touched = false;
			
			touchedPoint.x=m_playerFollowed.getX()+m_playerFollowed.getSizeX()/2;
			touchedPoint.y=m_playerFollowed.getY()+m_playerFollowed.getSizeY()/2;
						
			tempV.x = (touchedPoint.x-m_ghost.getCenter().x);
			tempV.y = (touchedPoint.y-m_ghost.getCenter().y);
			
			if(Math.abs(tempV.x)<200)if(Math.abs(tempV.y)<200)
			{
				if(backTemp>0)backTemp-=pSecondsElapsed;
				else followStatus=FollowStatus.Gaming;
			}
		}
		else if(followStatus==FollowStatus.Start)
		{
			tempV.x=0;
			tempV.y=0;
			delayLightOn--;
			if(delayLightOn<0)followStatus = FollowStatus.Blacking;
			
		}
		else if(followStatus==FollowStatus.Blacking)
		{
			m_ghost.LightOnCamera();
			tempV.x=0;
			tempV.y=0;
			
			if(m_ghost.isLightOn())followStatus = FollowStatus.ShowingDoor;			
		}
		
		tempV.x *= pSecondsElapsed;
		tempV.y *= pSecondsElapsed;
		
		m_ghost.setLinearVelocity(tempV);
		m_ghost.onUpdate();	
	}
	
	public void CameraLightOn()
	{
		m_ghost.LightOnCamera();
	}
	
	public void CameraLightOff()
	{
		m_ghost.LightOffCamera();
	}	
	
	public void CameraLightOff(float time)
	{
		m_ghost.LightOffCamera(time);
	}
	
	public boolean isLightOn()
	{
		return m_ghost.isLightOn();
	}
	
	public boolean isLightOff()
	{
		return m_ghost.isLightOff();
	}

	@Override
	public void reset() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void rotate(float angle) {
		// TODO Auto-generated method stub
		
	}
}
